#ifndef __BASE_EVENT_HPP__
#define __BASE_EVENT_HPP__

#include <string>
#include <iostream>
#include <algorithm>
#include <utility>

#include "../judge_types/allJudgeTypes.h"
#include "run_code_params.h"
#include "../judge_events/strategy.hpp"
#include "../utility/type_traits.hpp"


template <class judge_type_t>
class run_code_context_t;

namespace run_code_event_space {

using std::string;
using std::operator""s;
using std::cout;
using std::endl;
using std::make_tuple;
using std::cref;    
using std::max;

// 如果event->execute_impl需要额外传参，则需要在judge_type中实现一个默认版本custom_param
template <class T>
struct base_event {
    template <class U>
    decltype(auto) execute(run_code_context_t<U>& context) {
        context.judge_type.pre_execute(T{});
        auto params = context.judge_type.custom_params(T{});
        auto res = execute_expend(context, params, std::make_index_sequence<std::tuple_size_v<std::decay_t<decltype(params)>>>{});
        context.judge_type.post_execute(T{}, res);
        return res;
    }

    template <class U, class... Args, size_t... Index>
    decltype(auto) execute_expend(run_code_context_t<U>& context, const std::tuple<Args...>& args, std::index_sequence<Index...> /*unused*/) {
        auto res = static_cast<T*>(this)->execute_impl(context, std::get<Index>(args)...);
        return res;
    }
};

}


#endif /* __BASE_EVENT_HPP__ */
